﻿namespace Frameworks
{
    using System.Collections.Generic;
    using System.Linq;

    public sealed class EventDispatcher
    {
       private Dictionary<object, EventListenerDelegate> _eventCallbackMap;

        public bool AddEventListener(object type, EventListenerDelegate callback)
        {
            if (callback == null) return false;

            if (_eventCallbackMap == null)
                _eventCallbackMap = new Dictionary<object, EventListenerDelegate>();

            if (_eventCallbackMap.ContainsKey(type))
                _eventCallbackMap[type] += callback;
            else
                _eventCallbackMap.Add(type, callback);

            return true;
        }

        public bool RemoveEventListener(object type, EventListenerDelegate callback)
        {
            if (callback == null) return false;

            if (_eventCallbackMap == null) return false;

            if (_eventCallbackMap.ContainsKey(type))
            {
                _eventCallbackMap[type] -= callback;
                return true;
            }
            else return false;
        }

        public bool RemoveEventListener(object type)
        {
            if (_eventCallbackMap == null) return false;

            if (_eventCallbackMap.ContainsKey(type))
            {
                _eventCallbackMap.Remove(type);
                return true;
            }
            else return false;
        }

        public void RemoveAll()
        {
            if (_eventCallbackMap != null)
                _eventCallbackMap.Clear();
        }

        public bool BroadcastEvent(object type, EventData eventData)
        {
            if (_eventCallbackMap == null) return false;

            if (_eventCallbackMap.ContainsKey(type))
            {
                if (_eventCallbackMap[type] != null)
                {
                    _eventCallbackMap[type](eventData);
                    return true;
                }
                else return false;
            }
            else return false;
        }

        public bool BroadcastEvent(EventData eventData)
        {
            if (_eventCallbackMap == null) return false;

            if (eventData == null) return false;

            object type = eventData.type;
            if (_eventCallbackMap.ContainsKey(type))
            {
                if (_eventCallbackMap[type] != null)
                {
                    _eventCallbackMap[type](eventData);
                    return true;
                }
                else return false;
            }
            else return false;
        }

        public bool HasEventListener(object type)
        {
            if (_eventCallbackMap == null) return false;

            if (_eventCallbackMap.ContainsKey(type)) return true;
            else return false;
        }

        public bool HasEventListener(object type, EventListenerDelegate callback)
        {
            if (callback == null) return false;

            if (_eventCallbackMap == null) return false;

            List<System.Delegate> list;
            if (_eventCallbackMap.ContainsKey(type))
            {
                list = _eventCallbackMap[type].GetInvocationList().ToList();
                return list.Contains<System.Delegate>(callback);
            }
            else return false;
        }

        public void Destory()
        {
            RemoveAll();
            _eventCallbackMap = null;
        }
    }
}
